package com.ruoyi.system.service.impl.fxImpl;

import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.fx.FxOrder;
import com.ruoyi.system.domain.fx.FxUser;
import com.ruoyi.system.domain.vo.FxMoneyVo;
import com.ruoyi.system.domain.vo.UserVo;
import com.ruoyi.system.domain.vo.statistic.*;
import com.ruoyi.system.mapper.fx.StatisticMapper;
import com.ruoyi.system.service.fx.IFxOrderService;
import com.ruoyi.system.service.fx.IFxStoreService;
import com.ruoyi.system.service.fx.IFxUserService;
import com.ruoyi.system.service.fx.statistic.IStatisticService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;


/**
 * 统计
 */
@Service
public class StatisticServiceImpl implements IStatisticService
{

    @Autowired
    private StatisticMapper statisticMapper;

    @Autowired
    private IFxUserService fxUserService;

    @Autowired
    private IFxStoreService fxStoreService;
    @Autowired
    private IFxOrderService fxOrderService;

    /**
     * 总后台统计
     * @return
     */
    @Override
    public TopStatisticVo selectTop() {
        TopStatisticVo vo = Optional.ofNullable(statisticMapper.selectTop()).orElse(new TopStatisticVo());
        UserChartVo userChartVo = this.selectUserChart();
        vo.setUserChartVo(userChartVo); // 用户增长统计图
        List<OrderChartVo> list = this.selectOrderChart(null);
        vo.setOrderChartVos(list);
        DealVo dealVo = this.selectDealVo(null);
        vo.setDealVo(dealVo); // 流水统计
        return vo;
    }

    /**
     * 商家统计
     * @return
     */
    @Override
    public StoreStatisticVo selectStore(Long storeId) {

        FxUser fxUser = fxUserService.selectFxUserByUserId(SecurityUtils.getUserId());
        Long sid = StringUtils.isNotNull(fxUser) ? StringUtils.isNotNull(fxUser.getStoreId()) ? fxUser.getStoreId() : null : null;
        StoreStatisticVo vo = Optional.ofNullable(statisticMapper.selectStore(sid)).orElse(new StoreStatisticVo());
        List<FxUser> userList = fxUserService.selectTeamNumber(sid);
        vo.setTeamNum(StringUtils.isNotEmpty(userList) ? String.valueOf(userList.size()) : "0");
        FxMoneyVo moneyVo = getAblewithdrawal();
        UserChartVo userChartVo = this.selectUserChart();
        vo.setUserChartVo(userChartVo); // 用户增长统计图
        List<OrderChartVo> list = this.selectOrderChart(sid);
        vo.setOrderChartVos(list);
        DealVo dealVo = this.selectDealVo(sid);
        vo.setDealVo(dealVo); // 流水统计
        vo.setTotalOrderCount(moneyVo.getWithdrawn()); // 总提现金额
        vo.setCanWithdrawal(moneyVo.getNotWithdrawn()); // 可提现金额
        return vo;
    }

    /**
     * 供应商统计
     * @return
     */
    @Override
    public SupplierStatisticVo selectSupplier(Long supplierId) {
        FxUser fxUser = fxUserService.selectFxUserByUserId(SecurityUtils.getUserId());
        Long pid = StringUtils.isNotNull(fxUser) ? StringUtils.isNotNull(fxUser.getParentAccountId()) ? fxUser.getParentAccountId() : null : null;

        SupplierStatisticVo vo = Optional.ofNullable(statisticMapper.selectSupplier(pid)).orElse(new SupplierStatisticVo());
        UserChartVo userChartVo = this.selectUserChart();
        vo.setUserChartVo(userChartVo); // 用户增长统计图
        List<OrderChartVo> list = this.selectOrderChart(pid);
        vo.setOrderChartVos(list);
        DealVo dealVo = this.selectDealVo(pid);
        vo.setDealVo(dealVo); // 流水统计
        return vo;
    }

    /**
     * 用户增涨统计图
     *
     * @return
     */
    @Override
    public UserChartVo selectUserChart() {

        UserChartVo vo = new UserChartVo();

        // 把全部用户按照 半个月统计 分类 并统计数量
        List<UserVo> userVo = Optional.ofNullable(statisticMapper.selectUserDay()).orElse(new ArrayList<>());
        Map<String, UserVo> map = userVo.stream().collect(Collectors.toMap(UserVo::getDay,item -> item));

        // 获取今天的日期
        LocalDate today = LocalDate.now();

        // 创建一个 DateTimeFormatter 用于格式化日期
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

        // 用于存储日期字符串的列表
        List<String> dateStrings = new ArrayList<>();
        List<Long> expectedData = new ArrayList<>();
        List<Long> actualData = new ArrayList<>();
        // 计算今天之前的 15 天日期，并将其转换为字符串
        for (int i = 0; i < 15; i++) {
            LocalDate date = today.minusDays(i);
            String formattedDate = date.format(formatter);
            dateStrings.add(formattedDate.substring(5));
            UserVo user = map.get(formattedDate);
            // TODO 暂写随机数
//            expectedData.add((long) new Random().nextInt(11));
            if (StringUtils.isNotNull(user)) {
                actualData.add(user.getUserCount());
                continue;
            }
            actualData.add(0L);
        }
        Collections.reverse(actualData);
        Collections.reverse(dateStrings);
        vo.setExpectedDate(expectedData);
        vo.setActualData(actualData);
        vo.setDate(dateStrings);
        return vo;
    }

    /**
     * 订单饼状图
     *
     * @return
     */
    @Override
    public List<OrderChartVo> selectOrderChart(Long number) {
        List<Long> roles = SecurityUtils.getLoginUser().getUser().getRoles().stream().map(SysRole::getRoleId).collect(Collectors.toList());
        FxOrder order = new FxOrder();
//        FxUser fxUser = new FxUser();
//        if (!roles.contains(1L) || !roles.contains(6L)) {
//            fxUser = fxUserService.selectFxUserByUserId(SecurityUtils.getUserId());
//        }
        if (roles.contains(3L)) { // 供应商
            order.setOrderType(1L);
            order.setSupplierId(String.valueOf(number));
        }
        if (roles.contains(4L)) { // 店铺
            order.setStoreId(number);
        }
        OrderStatusVo vo = statisticMapper.selectOrderChart(order);
        Long onLine = vo.getOnLine();
        Long below = vo.getBelow();
        Long purchase = vo.getPurchase();
        return Arrays.asList(
                new OrderChartVo().setName("线上订单").setValue(onLine),
                new OrderChartVo().setName("线下订单").setValue(below),
                new OrderChartVo().setName("采购订单").setValue(purchase)
        );
    }

    /**
     * 日 单流水
     * @return
     */
    @Override
    public DealVo selectDealVo(Long number) {

        List<Long> roles = SecurityUtils.getLoginUser().getUser().getRoles().stream().map(SysRole::getRoleId).collect(Collectors.toList());
        FxOrder order = new FxOrder();
//        FxUser fxUser = new FxUser();
//        if (!roles.contains(1L) || !roles.contains(6L)) {
//            fxUser = fxUserService.selectFxUserByUserId(SecurityUtils.getUserId());
//        }
        if (roles.contains(3L)) { // 供应商
            order.setOrderType(1L);
            order.setSupplierId(String.valueOf(number));
        }
        if (roles.contains(4L)) { // 店铺
            order.setStoreId(number);
        }

        DealVo dealVo = new DealVo();
        List<OrderStatusVo> vo = statisticMapper.selectFlowingWaters(order);

        // 定义日期格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM-dd");
        // 获取今天的日期
        LocalDate today = LocalDate.now();
        List<String> dateList = Stream.iterate(today, e -> e.minusDays(1))
                .limit(15)
                .map(e -> e.format(formatter))  // 格式化日期
                .collect(Collectors.toList());

        Map<String, String> map = Optional.ofNullable(vo).orElseGet(ArrayList::new)
                .stream().collect(Collectors.toMap(OrderStatusVo::getOrderDate, e -> {
            BigDecimal money = new BigDecimal(e.getPayMoney()).add(new BigDecimal(e.getExpend()));
            return money.toString();
        }));

        Map<String, String> resultMap = new LinkedHashMap<>();

        for (String str : dateList) {
            String money = map.get(str);
            if (StringUtils.isEmpty(money)) {
                resultMap.put(str, "0.00");
            }else {
                resultMap.put(str, money);
            }
        }
        List<String> strList = new ArrayList<>(resultMap.values());
        Collections.reverse(dateList);
        Collections.reverse(strList);
        dealVo.setDate(dateList);
        dealVo.setFlowingWater(strList);

        return dealVo;
    }

    public FxMoneyVo getAblewithdrawal() {
        List<Long> roles =  SecurityUtils.getLoginUser().getUser().getRoles()
                .stream().map(SysRole::getRoleId).collect(Collectors.toList());
        if (roles.contains(1L) || roles.contains(6L)) {
            return new FxMoneyVo();
        }
        FxUser fxUser = fxUserService.selectFxUserByUserId(SecurityUtils.getUserId());
        FxOrder fxorder = new FxOrder();
        if(fxUser.getRoleType() == 4){
            fxorder.setOrderType(2L);
            fxorder.setStoreId(fxUser.getStoreId());
        }
        return fxOrderService.getTotalMoney(fxorder);
    }
}
